package it.alertManager.activity;

import it.alertManager.exceptions.AlertManagerException;
import it.alertManager.util.CommonData;
import it.alertManager.weather.HTTPWeatherReader;
import it.alertManager.weather.WeatherData;

import java.io.IOException;
import java.util.List;
import java.util.Locale;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.KeyguardManager;
import android.app.NotificationManager;
import android.app.KeyguardManager.KeyguardLock;
import android.location.Address;
import android.location.Criteria;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.media.AudioManager;
import android.os.Bundle;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnUtteranceCompletedListener;
import android.util.Log;
import android.widget.Toast;

public class AlarmReceiveActivity extends Activity {

	private TextToSpeech textToSpeech;
	private HTTPWeatherReader httpWeatherReader;
	private WeatherData weatherData;

	private Locale deviceLanguage;
	private WakeLock wakeLock;
	private KeyguardLock mLock;
	private Geocoder gcd;
	private String city; 

	private LocationManager locationManager;


	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		// Acquire a reference to the system Location Manager
		locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
		final Geocoder gcd = new Geocoder(this, Locale.getDefault());
		Criteria criteria = new Criteria();
		criteria.setBearingRequired(true);
		String bestProvider = locationManager.getBestProvider(criteria, true);

		// Define a listener that responds to location updates
		LocationListener locationListener = new LocationListener() {
			public void onLocationChanged(Location location) {
				// Called when a new location is found by the network location provider.

				List<Address> addresses = null;
				try {
					addresses = gcd.getFromLocation(location.getLatitude(), location.getLongitude(), 1);
				} catch (IOException e) {
					e.printStackTrace();
				}
				if (null!= addresses && addresses.size() > 0) {
					city = addresses.get(0).getLocality();
				}
				else{
					city = getLocation();
//					List<String> providerList = locationManager.getAllProviders();
//					long delta = System.currentTimeMillis();
//					long now = System.currentTimeMillis();
//					Location tempLocation = null;
//					String bestProvider = null;
//					for (String provider : providerList) {
//						tempLocation = locationManager.getLastKnownLocation(provider);
//						if (null == tempLocation)
//							continue;
//						if (now - tempLocation.getTime() < delta){
//							delta = now - tempLocation.getTime();
//							bestProvider = provider;
//						}
//					}
//					try
//					{
//						tempLocation = locationManager.getLastKnownLocation(bestProvider);
//						addresses = gcd.getFromLocation(tempLocation.getLatitude(), tempLocation.getLongitude(), 1);
//						city = addresses.get(0).getLocality();
//					} catch (IOException e) {
//						// TODO Auto-generated catch block
//						e.printStackTrace();
//					}
				}
				new AlertDialog.Builder(AlarmReceiveActivity.this)
				.setTitle("You are in")
				.setIcon(R.drawable.small_blue_ball)
				.setMessage(city).show();
				locationManager.removeUpdates(this);
				textToSpeech.speak("Previsioni del tempo di " + city, TextToSpeech.QUEUE_ADD, null);
				wakeUpWeather(city);
			}

			public void onStatusChanged(String provider, int status, Bundle extras) {}

			public void onProviderEnabled(String provider) {}

			public void onProviderDisabled(String provider) {
				city = getLocation();
			}
		};

		locationManager.requestLocationUpdates(bestProvider,0,1000,locationListener);
		city = getLocation();

		KeyguardManager mKeyGuardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
		mLock = mKeyGuardManager.newKeyguardLock(AlarmReceiveActivity.class.getName());
		mLock.disableKeyguard();		
		PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);

		wakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, AlarmReceiveActivity.class.getName());
		wakeLock.acquire(); 
		textToSpeech = new TextToSpeech(this, new TextToSpeech.OnInitListener() {

			public void onInit(int status) {
				Log.d("LOG_CLASS_NAME","STARTING SPEAKER!!!!!!!!");
				deviceLanguage = getResources().getConfiguration().locale;		
				textToSpeech.setSpeechRate(CommonData.SPEACH_RATE);
				//wakeUpWeather(null);
			}

		});
		textToSpeech.setOnUtteranceCompletedListener(new OnUtteranceCompletedListener() {

			public void onUtteranceCompleted(String utteranceId) {
				// TODO Auto-generated method stub
				Log.d("LOG_CLASS_NAME","STARTING FINISHED!!!!!!!!");
				textToSpeech.shutdown();
			}
		});
		setContentView(R.layout.main);

		// Cancel the notification -- we use the same ID that we had used to start it
		((NotificationManager)getSystemService(NOTIFICATION_SERVICE)).cancel(R.layout.main);

		// Tell the user we stopped.
		Toast.makeText(this, "Sveglia disattivata", Toast.LENGTH_SHORT).show();		
		AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
		audioManager.playSoundEffect(AudioManager.FX_KEY_CLICK);

		if (wakeLock != null && wakeLock.isHeld())
			wakeLock.release();

	}

	@Override
	protected void onDestroy() {
		if (wakeLock != null && wakeLock.isHeld())
			wakeLock.release();

		mLock.reenableKeyguard();
		textToSpeech.shutdown();

		super.onDestroy();
	}

	private void wakeUpWeather(String city){
		//city = "Milano";
		if (!"".equals(city))
		{
			try 
			{
				httpWeatherReader = new HTTPWeatherReader();
				weatherData = httpWeatherReader.getURLOfWeatherForecast(city, deviceLanguage);
				if (weatherData.getWeatherURL() == null || "".equals(weatherData.getWeatherURL()))
				{
					try {
						httpWeatherReader.readWeatherForecastForIt(getResources(), textToSpeech, "http://meteo.libero.it" + city, null);
					} catch (AlertManagerException e) {
						Toast.makeText(AlarmReceiveActivity.this, e.getMessage(), CommonData.TOAST_3_SECOND_LENGTH).show();
					}
					Log.d(ConfigurationActivity.class.getName(), "Closing dialog");	
				}
				else
				{
					try {
						if (deviceLanguage.getLanguage().equals(Locale.ITALIAN.toString()))
							httpWeatherReader.readWeatherForecastForIt(getResources(), textToSpeech, weatherData.getWeatherURL(), null);
						else if (deviceLanguage.getLanguage().equals(Locale.ENGLISH.toString()))
							httpWeatherReader.readWeatherForecastForEN(getResources(), textToSpeech, weatherData.getWeatherURL(), null);
					} catch (AlertManagerException e) {
						Toast.makeText(AlarmReceiveActivity.this, e.getMessage(), CommonData.TOAST_3_SECOND_LENGTH).show();
					}						

				}
			} catch (AlertManagerException e) {
				Toast.makeText(AlarmReceiveActivity.this, e.getMessage(), CommonData.TOAST_3_SECOND_LENGTH).show();
			}
		}		
	}

	private String getLocation(){
		long minTime = 0, bestTime = 0;
		Location bestResult, bestLocation = null;
		float  bestAccuracy = 0;
		String city = "";
		List<String> matchingProviders = locationManager.getAllProviders();
		for (String provider: matchingProviders) {
			Location location = locationManager.getLastKnownLocation(provider);
			if (location != null) {
				float accuracy = location.getAccuracy();
				long time = location.getTime();

				if ((time > minTime && accuracy < bestAccuracy)) {
					bestResult = location;
					bestAccuracy = accuracy;
					bestTime = time;
				}
				else if (time < minTime && 
						bestAccuracy == Float.MAX_VALUE && time > bestTime){
					bestResult = location;
					bestTime = time;
				}
			}
		}
		if (null != bestLocation){
			List<Address> addresses;
			try {
				addresses = gcd.getFromLocation(bestLocation.getLatitude(), bestLocation.getLongitude(), 1);
				city = addresses.get(0).getLocality();
			} catch (IOException e) {
				Toast.makeText(AlarmReceiveActivity.this, e.getLocalizedMessage(), Toast.LENGTH_LONG);
				e.printStackTrace();
			}
		}
		return city;
	}

}
